package modele;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Vector;

import org.jdom.JDOMException;

import outils.Divers;

public class ModeleJava extends ModeleLangage{

	private final String lng = "JAVA";
	private final String format = ".java";
	private String[] tabEqui;
	public ModeleJava(String modeleFic, String equivalType, Vector<ModeleClasse> listeClasse,Vector<ModeleRelation> listeRelation) throws JDOMException, IOException
	{
		super.setLangage(lng);
		super.setFormat(format);
		super.setModeleFichier(modeleFic);
		super.equivalentTypes = equivalType;
		super.setListeClasse(listeClasse);
		super.listeRelation = listeRelation;
		tabEqui = Divers.getLangageType(super.equivalentTypes);
	}
	

	private String getTypeAdequat(Types t)
	{
		String leType = "";
		switch(t)
		{
			case CHAR: leType = tabEqui[ModeleLangage.CHAR];
			break;
			case INT: leType = tabEqui[ModeleLangage.INT] ;
			break;
			case STRING: leType = tabEqui[ModeleLangage.STRING] ;
			break;
			case FLOAT: leType = tabEqui[ModeleLangage.FLOAT] ;
			break;
			case DOUBLE: leType = tabEqui[ModeleLangage.DOUBLE] ;
			break;
			case LONG: leType = tabEqui[ModeleLangage.LONG] ;
			break;
			case SHORT: leType = tabEqui[ModeleLangage.SHORT] ;
			break;
		}
		return leType;
	}
	
	private String goodType(String type)
	{
		String leType;
		//on verifie si c'est un type connu ou pas
		Types t = Divers.stringToType(type);
		
		//si inconnu on le réécrit tel quel
		if(t == null)
			leType = type;
		
		//sinon on met son équivalent
		else
			leType=" "+this.getTypeAdequat(t);
		
		return leType;
	}
	
	public void genereCode(String dossierDestination) throws IOException 
	{
		String lecture = "",nomClasse = "",cons = "",att = "", meth = "";
		Types t;
		File ficClasse;
		File modeleSquelette = new File(this.modeleFichier);

		//lecteur du modele
		BufferedReader bf;
		//ecrivain sur le fichier de classe
		BufferedWriter wr;
		if(!listeClasse.isEmpty())
		{
			for(int i = 0; i <listeClasse.size(); i++)
			{
			
				nomClasse = Divers.nomClasseCorrect(listeClasse.get(i).getNom());
				System.out.println("--generation de la classe "+nomClasse);
				ficClasse = new File(dossierDestination+"/"+nomClasse+this.format);
				
				//on réouvre le fichier modele
				bf =  new BufferedReader(new FileReader(modeleSquelette));
				
				//on écrit sur le nouveau fichier
				wr = new BufferedWriter(new FileWriter(ficClasse));
				//on parcourt le fichier modele
				while( (lecture = bf.readLine()) != null)
				{
					String tabLine [] = lecture.split(" ");
					for(int j =0; j<tabLine.length; j++)
					{				
						if(tabLine[j].equals("[name]"))
						{
							wr.write(nomClasse);
						}
						else if(tabLine[j].equals("[constructeur]"))
						{
							cons+= "\tpublic "+nomClasse +" () {" ;
							cons+=	"\n\t\t// TODO Auto-generated constructor stub";
							cons+= "\n\t}";

							wr.write(cons);
						}
						else if(tabLine[j].equals("[attributs]"))
						{
							//si la classe possède au moins un attribut
							if(this.listeClasse.get(i).isAt())
							{
								System.out.println("---ecriture des attributs");
								//on réecrit les attributs
								Vector<ModeleAttribut> listeAtt = this.listeClasse.get(i).getAttributs();
								for(int k = 0 ; k < listeAtt.size(); k++)
								{
									//ecriture de la visibilite
									att +="\t"+(listeAtt.get(k).getVisib().toString()).toLowerCase();
									
									//ecriture du bon type
									att +=" "+this.goodType(listeAtt.get(k).getType());
									
									//ecriture du nom
									att+=" "+listeAtt.get(k).nom;
									att+=";";
									wr.write(att);
									wr.write("\n");
								}
							}
						}
						else if(tabLine[j].equals("[methodes]"))
						{
							if(this.listeClasse.get(i).isMeth())
							{
								System.out.println("---ecriture des methodes");
								Vector<ModeleMethode> listMeth = this.listeClasse.get(i).getMethodes();
								String ar = "arg";
								for(int k=0; k < listMeth.size(); k++)
								{
									ModeleMethode temp = listMeth.get(k);
									 meth ="\n\t"+ temp.getVisib()+" "+this.goodType(temp.getTypeRetour().toLowerCase())+" "+temp.getNom();
									meth+="(";
									if(!temp.getListeArgs().isEmpty())
									{
										Vector<String> tempA = temp.getListeArgs();
										for(int l= 0; l <tempA.size();l++)
										{
											
												meth+=this.goodType(tempA.get(l))+" "+ar+l;
											if(l != tempA.size()-1)
												meth+=",";
												
										}
									}
									meth+=")";
									meth+=" {";
									meth+="\n\t\t // TODO Auto-generated method stub";
									meth+="\n\t}";
									wr.write(meth);
								}
							}
						}	
						else
						{
							wr.write(tabLine[j]);
						}
						wr.write(" ");
					}
					wr.write("\n");
				}//end while
				wr.flush();
				bf.close();
			}//end for
		}
		
	}
}
